#pragma  once

//#include "Array.h"

#include <windows.h>
#include <boost/any.hpp>
#include <boost/lexical_cast.hpp>
#include <map>
#include <vector>
using namespace std;

//count 是数组的个数,  不是字节数
//这个速度[可能]较快, 用于bool/char/short/int/long/float/double等基本类型的数组拷贝
template<typename T>
void ArrayCopy(const T* srcArray, int srcOffset, T* destArray, int destOffset, size_t count) {
	if (!count) {
		return;
	}
	srcArray += srcOffset;
	destArray += destOffset;
	if (srcArray == destArray) {
		return;
	}
	memmove(destArray, srcArray, count * sizeof(T));
}
//count 是数组的个数,  不是字节数
//用于对象数组拷贝, operator =, 也可用于基本类型拷贝
template<typename T>
void ArrayCopyEx(const T* srcArray, int srcOffset, T* destArray, int destOffset, size_t count) {
	if (!count) {
		return;
	}
	srcArray += srcOffset;
	destArray += destOffset;
	if (srcArray == destArray) {
		return;
	}
	const T* src = srcArray;
	T* dst = destArray;
	if (destArray < srcArray) {
		while (count--) {
			*dst++ = *src++;
		}
	} else {
		src += count;
		dst += count;
		while (count--) {
			*--dst = *--src;
		}
	}
}

template<typename X, typename Y>
X LexicalCast(const Y& y, X defVal = X()) {
	try {
		return boost::lexical_cast<X>(y);
	} catch (...) {
	}
	return defVal;
}

class Runnable {
public:
	virtual ~Runnable() {};
	virtual void Run() = 0;
};


class WithProperties {
	typedef map<wstring, boost::any> PropertiesType;
public:
	boost::any GetProperty(wstring propertyName, boost::any defaultValue = boost::any());
	void SetProperty(wstring propertyName, boost::any value);
	template<typename T>
	T GetProperty(wstring propertyName, T defaultValue = T()) {
		boost::any value = GetProperty(propertyName);
		if (!value.empty()) {
			return boost::any_cast<T>(value);
		}
		return defaultValue;
	}
	void Clear() {
		properties_.clear();
	}
private:
	PropertiesType properties_;
};


template<typename T>
class Singlton {
public:
	static T& Instance() {
		static T t;
		return t;
	}
};

template<typename T>
class Singlton2 {
	static T* instance;
public:
	static T& Instance(bool autoCreate = true) {
		if (autoCreate && !instance) {
			instance = new T();
		}
		return *instance;
	}
	static void DestroyInstance() {
		if (instance) {
			delete instance;
			instance = 0;
		}
	}
};
template<typename T>
T* Singlton2<T>::instance = 0;

namespace util {
using namespace std;

void dbg(wstring ws);
void dbg(string s);
void ShowLastError();

//!功能:连接路径, .
/*!
 \举例:
 \	JoinPath(L"c:\\a", L"b", L"c.txt") ==> c:\a\b\c.txt
 \	JoinPath(L"c:\\a", L"b", L"c") ==> c:\a\b\c
 \	JoinPath(L"c:\\a", L"b", L"c\\") ==> c:\a\b\c		//不是c:\a\b\c\, 因为c:\a\b\c是一个有效的文件或目录, 但是c:\a\b\c\不是文件或目录(是路径的一部分)
 \	JoinPath(L"c:\\a", L"\\b\\", L"c\\") ==> c:\a\b\c
 */
wstring JoinPath(wstring path, wstring path1 = L"", wstring path2 = L"", wstring path3 = L"", wstring path4 = L"", wstring path5 = L"", wstring path6 = L"", wstring path7 = L"", wstring path8 = L"", wstring path9 = L"");

//!功能:获取当前exe程序的文件全路径:  c:\xxx\xx\xxx.exe
/*!
 \author 杨恩涛
 \func    GetExeFile
 \data 2010-7-22 10:10:16
 \    @return wstring
 */
wstring GetExeFile();

//!功能:获取当前exe程序所在的目录, 不包含最后的'\':  c:\a\b
/*!
 \author 杨恩涛
 \func    GetAppPath
 \data 2010-7-22 10:11:09
 \    @return wstring
 */
wstring GetAppPath();

//!功能: 处理当前windows消息.
/*!
 \author 杨恩涛
 \func    ProcessCurrentMesssage
 \data 2010-7-22 10:09:35
 \    @return void
 */
void ProcessCurrentMesssage();
void OutStr(wstring ws);
void OutStr(string s);
wstring ToWString(string s, DWORD cp = CP_ACP);
string ToString(wstring s, DWORD cp = CP_ACP);

vector<string> OpenFileDialog(HWND parent = 0, bool multi = false);
string SaveFileDialog(HWND parent = 0);
int FontSizeToHeight(HDC dc, int size);
int GenerateID();

}
;

